import 'package:flutter/material.dart';
import 'package:x3_charts_core/model/funnel_chart_data_model.dart';

///**
///* @author hrongyong
///* @date   2/4/21
///* @email hrongyong@gmail.com
///* Description: 漏斗图
///*/
class FunnelChartPainter extends CustomPainter {
  final List<FunnelChartDataModel> chartModelList;

  ///是否显示副标题
  final bool isShowSubTitle;

  ///背景色
  final Color backgroundColor;

  FunnelChartPainter({@required this.chartModelList, this.isShowSubTitle = true, this.backgroundColor = Colors.white}) {
    _areas = chartModelList.length;
    areaPaint = Paint()
      ..isAntiAlias = true
      ..style = PaintingStyle.fill;
    bgPath = Path();
  }

  ///共有多少个区域
  int _areas = 0;

  ///每个区域的高度
  double _areaHeight = 0.0;

  ///画笔和路径
  Paint areaPaint;
  Path bgPath;

  ///文字
  final TextPainter _textPainter = TextPainter(textDirection: TextDirection.ltr);

  @override
  void paint(Canvas canvas, Size size) {
    _areaHeight = size.height / _areas;

    ///绘制背景
    canvas.drawRect(Offset.zero & size, Paint()..color = backgroundColor);

    ///漏斗
    drawArea(canvas, size);

    ///漏斗里面的文字title
    drawAreaTitle(canvas, size);
  }

  void drawAreaTitle(Canvas canvas, Size size) {
    for (int i = 0; i < chartModelList.length; i++) {
      ///获取区域的中心点，再根据文字的size偏移
      double x = size.width / 2;
      double y = _areaHeight / 2 + _areaHeight * i;
      _drawAxisText(
        canvas,
        size,
        title: chartModelList[i].title,
        subTitle: chartModelList[i].subTitle,
        offset: Offset(x, y),
        index: i,
      );
    }
  }

  ///标题和副标题一起绘制
  void _drawAxisText(
    Canvas canvas,
    Size size, {
    String title,
    String subTitle,
    Offset offset = Offset.zero,
    int index,
  }) {
    ///绘制标题
    TextSpan text = TextSpan(text: title, style: TextStyle(fontSize: 6, color: Colors.black));
    _textPainter.text = text;
    _textPainter.layout(); // 进行布局
    Size textSize = _textPainter.size;
    Offset textOffsetPos;
    if (index == _areas - 1) {
      textOffsetPos = Offset(offset.dx - textSize.width / 2, offset.dy - _areaHeight / 2 + _areaHeight * (1 / 3));
    } else {
      textOffsetPos = Offset(offset.dx - textSize.width / 2, offset.dy - textSize.height / 2);
    }
    _textPainter.paint(canvas, textOffsetPos);

    if (isShowSubTitle) {
      ///绘制副标题
      TextSpan subText = TextSpan(text: subTitle, style: TextStyle(fontSize: 6, color: Colors.black));
      _textPainter.text = subText;
      _textPainter.layout(); // 进行布局
      Size subTextSize = _textPainter.size;
      Offset subTextOffsetPos;
      double subX = 0.0;
      double subY = offset.dy - subTextSize.height / 2;
      if (chartModelList[index].value == 0.0) {
        subX = offset.dx + textSize.width;
      } else {
        if (index == 0) {
          subX = offset.dx + (size.width + chartModelList[index + 1].value * size.width) / 4;
        } else if (index == _areas - 1) {
          ///斜率  （size.width/2,0）(size.width/2 + chartModelList[index].value * size.width / 2,_areaHeight)
          double _kSlope = (_areaHeight - 0) / (size.width / 2 + chartModelList[index].value * size.width / 2 - size.width / 2);

          ///点斜式 （size.width/2,0）
          /// y = k(x - x0) + y0; -> (y - y0)/k + x0 = x
          subX = (_areaHeight * (2 / 3) - 0) / _kSlope + size.width / 2;
          subY = offset.dy - _areaHeight / 2 + _areaHeight * (1 / 3);
        } else {
          subX = offset.dx + (chartModelList[index].value * size.width + chartModelList[index + 1].value * size.width) / 4;
        }
      }

      subTextOffsetPos = Offset(subX + 5, subY);
      _textPainter.paint(canvas, subTextOffsetPos);
    }
  }

  void drawArea(Canvas canvas, Size size) {
    ///循环获取确定路径并绘画
    for (int i = 0; i < chartModelList.length; i++) {
      if (chartModelList[i].value == 0.0) {
        if (i == chartModelList.length - 1) {
          canvas.drawLine(
              Offset(size.width / 2, _areaHeight * i),
              Offset(size.width / 2, size.height),
              Paint()
                ..color = chartModelList[i].color
                ..strokeWidth = 2);
        } else {
          canvas.drawLine(
              Offset(size.width / 2, _areaHeight * i),
              Offset(size.width / 2, _areaHeight * (i + 1)),
              Paint()
                ..color = chartModelList[i].color
                ..strokeWidth = 2);
        }
        continue;
      }

      ///清理路径
      bgPath.reset();

      ///移动路径起点到指定位置
      bgPath.moveTo(size.width / 2 - chartModelList[i].value * size.width / 2, _areaHeight * i);
      if (i == chartModelList.length - 1) {
        bgPath.lineTo(size.width / 2, size.height);
      } else {
        bgPath.lineTo(size.width / 2 - chartModelList[i + 1].value * size.width / 2, _areaHeight * (i + 1));
        bgPath.lineTo(size.width / 2 + chartModelList[i + 1].value * size.width / 2, _areaHeight * (i + 1));
      }
      bgPath.lineTo(size.width / 2 + chartModelList[i].value * size.width / 2, _areaHeight * i);

      //闭合路径
      bgPath.close();

      ///绘制漏斗
      canvas.drawPath(bgPath, areaPaint..color = chartModelList[i].color);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
